package com.wuercloud.http.client;

import com.wuercloud.config.ApplicationConfig;
import com.wuercloud.http.json.codec.HttpJsonRequestEncoder;
import com.wuercloud.http.json.codec.HttpJsonResponseDecoder;
import com.wuercloud.http.json.pojo.InfoObject;
import com.wuercloud.http.json.pojo.MsgInfoFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpResponseDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

/**
 * Created by JiangWL on 2017/2/14.
 */
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class HttpJsonClient {
    private static Logger log = LoggerFactory.getLogger(HttpJsonClient.class);
    @Autowired
    private Environment environment;

    /**
     * 传递业务信息
     * 构建netty client服务执行业务传送，业务传递端要进行业务处理需实现类接收对象进行自己业务操作
     * 本系统设计初衷业务端不需关注，只投递，实现覆盖类的方法是为特殊应用使用
     * @param infoObject
     * @throws Exception
     */
    public void delivery(final InfoObject infoObject) {
        // 配置客户端NIO线程组
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            ch.pipeline().addLast("http-decoder",
                                    new HttpResponseDecoder());
                            ch.pipeline().addLast("http-aggregator",
                                    new HttpObjectAggregator(65536));
                            // json解码器
                            ch.pipeline().addLast("json-decoder", new HttpJsonResponseDecoder(InfoObject.class));
                            ch.pipeline().addLast("http-encoder",
                                    new HttpRequestEncoder());
                            ch.pipeline().addLast("json-encoder",
                                    new HttpJsonRequestEncoder());
                            ch.pipeline().addLast("jsonClientHandler",
                                    new HttpJsonClientHandler(infoObject));
                        }
                    });

            // 发起异步连接操作
            ChannelFuture f = b.connect(new InetSocketAddress(environment.getProperty("http.server"),Integer.parseInt(environment.getProperty("http.server.port")))).sync();

            // 当代客户端链路关闭
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("连接错误，执行失败数据备份。。。");
        } finally {
            // 优雅退出，释放NIO线程组
            group.shutdownGracefully();
        }
    }

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
        HttpJsonClient httpJsonClient = (HttpJsonClient)context.getBean("httpJsonClient");
        httpJsonClient.delivery(MsgInfoFactory.createTestInfo());

    }
}
